package eteam.aps.systemservice.bll;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.engine.pinyin4j.Pinyin4jEngine;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import eteam.aps.common.QueryResult;
import eteam.aps.common.enumeration.SortEnum;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.systeminterface.model.dto.CustclassDto;
import eteam.aps.systeminterface.model.dto.CustomerDto;
import eteam.aps.systeminterface.model.dto.VerifyTokenDto;
import eteam.aps.systeminterface.model.entity.CustclassEntity;
import eteam.aps.systeminterface.model.entity.CustomerEntity;
import eteam.aps.systeminterface.model.enums.StateEnum;
import eteam.aps.systeminterface.model.reqparam.QueryCustomerParam;
import eteam.aps.systemservice.dal.CustomerDal;
import eteam.aps.systemservice.model.mapper.ICustclassMapper;
import eteam.aps.systemservice.model.mapper.ICustomerMapper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 客户资料相关业务类
 */
@Service
public class CustomerBll {
    @Autowired
    private CustomerDal customerDal;

    /**
     * 根据父级分类ID获取下级分类列表
     *
     * @param currentOrgId
     * @param parentId
     * @return
     */
    public List<CustclassEntity> getClassListByPid(String currentOrgId, String parentId) throws Exception {
        return customerDal.getClassListByPid(currentOrgId, parentId);
    }

    /**
     * 创建分类
     *
     * @param classDto: 请求参数
     * @throws Exception
     */
    public void createCustclass(VerifyTokenDto tokenDto, CustclassDto classDto) throws Exception {
        if (StrUtil.isEmpty(classDto.getFaboveid())) {
            throw new BusinessException("上级分类不存在");
        }
        CustclassEntity tmpCLass = customerDal.getClassById(classDto.getFaboveid());
        if (Helper.checkObjAllFieldsIsNull(tmpCLass)) {
            throw new BusinessException("上级分类不存在");
        }
        CustclassEntity entity = ICustclassMapper.INSTANCE.toEntity(classDto);
        entity.setFclassid(Helper.GetId());
        entity.setFinsidecode(tmpCLass.getFinsidecode() + "|" + entity.getFcode());
        entity.setFzjcode(getPinyinInitial(entity.getFname()));
        entity.setFrecorderorg(tokenDto.getFgrouporgid());
        entity.setFrecorder(tokenDto.getFuserid());
        entity.setFrecordername(tokenDto.getFfullname());
        entity.setFrecordtime(DateUtil.date());
        int count = customerDal.insertClass(entity);
        if (count < 1) {
            throw new BusinessException("创建客户分类失败");
        }
    }

    /**
     * 更新分类
     *
     * @param classDto: 请求参数
     * @throws Exception
     */
    public void updateCustclass(VerifyTokenDto tokenDto, CustclassDto classDto) throws Exception {
        if (StrUtil.isEmpty(classDto.getFaboveid())) {
            throw new BusinessException("上级分类不存在");
        }
        CustclassEntity tmpCLass = customerDal.getClassById(classDto.getFaboveid());
        if (Helper.checkObjAllFieldsIsNull(tmpCLass)) {
            throw new BusinessException("上级分类不存在");
        }
        CustclassEntity entity = ICustclassMapper.INSTANCE.toEntity(classDto);
        entity.setFinsidecode(tmpCLass.getFinsidecode() + "|" + entity.getFcode());
        entity.setFzjcode(getPinyinInitial(entity.getFname()));
        entity.setFlastmodifier(tokenDto.getFuserid());
        entity.setFlastmodifiername(tokenDto.getFfullname());
        entity.setFlastmodifytime(DateUtil.date());
        int count = customerDal.updateClass(entity);
        if (count < 1) {
            throw new BusinessException("更新客户分类失败");
        }
    }

    /**
     * 删除分类
     *
     * @param classId: 分类ID
     * @throws Exception
     */
    public void deleteCustclass(String classId) throws Exception {
        if (StrUtil.isEmpty(classId)) {
            throw new BusinessException("分类ID不存在");
        }
        Integer custCount = customerDal.getCustomerCountByPid(classId);
        if (custCount > 0) {
            throw new BusinessException("存在客户信息，不允许删除");
        }
        Integer childCount = customerDal.getClassCountByPid(classId);
        if (childCount > 0) {
            throw new BusinessException("存在子分类，不允许删除");
        }
        CustclassEntity retObj = customerDal.getClassById(classId);
        if (Objects.isNull(retObj)) {
            throw new BusinessException("分类不存在");
        }
        if (StringUtils.isEmpty(retObj.getFaboveid())) {
            throw new BusinessException("内置数据，不允许删除");
        }
        CustclassEntity tmpObj = new CustclassEntity();
        tmpObj.setFclassid(classId);
        tmpObj.setFcode(StrUtil.format("{}_{}", retObj.getFcode(), System.currentTimeMillis()));
        tmpObj.setFinsidecode(StrUtil.format("{}_{}", retObj.getFinsidecode(), System.currentTimeMillis()));
        tmpObj.setState(StateEnum.Delete.getValue());
        int count = customerDal.updateClass(tmpObj);
        if (count < 1) {
            throw new BusinessException("删除客户分类失败");
        }
    }


    /**
     * 分页查询客户列表
     *
     * @param queryParam
     * @return
     */
    public QueryResult<CustomerEntity> queryCustPageList(QueryCustomerParam queryParam) throws Exception {
        IPage<CustomerEntity> page = new Page<CustomerEntity>(queryParam.getPageIndex(), queryParam.getPageSize());
        QueryWrapper<CustomerEntity> wrapper = new QueryWrapper<CustomerEntity>();
        wrapper.eq("FClassId", queryParam.getClassid());
        if (CollUtil.isNotEmpty(queryParam.getStateArr()) && queryParam.getStateArr().stream().filter(p -> !Objects.isNull(p)).count() > 0) {
            List<Integer> tmpArr = queryParam.getStateArr().stream().filter(p -> !Objects.isNull(p)).map(p -> p.getValue()).collect(Collectors.toList());
            wrapper.in("State", tmpArr);
        } else {
            if (!queryParam.getState().equals(StateEnum.Delete)) {
                wrapper.eq("State", queryParam.getState().getValue());
            } else {
                wrapper.ne("State", StateEnum.Delete.getValue());
            }
        }
        if (StringUtils.isNotBlank(queryParam.getKeyword())) {
            wrapper.and(i -> i.like("FCode", queryParam.getKeyword())
                    .or().like("FName", queryParam.getKeyword())
                    .or().like("FShortName", queryParam.getKeyword())
                    .or().like("FZJCode", queryParam.getKeyword())
                    .or().like("FNickName", queryParam.getKeyword())
            );
        }
        if (StringUtils.isNotBlank(queryParam.getSortFields()) && queryParam.getSortOrder().equals(SortEnum.Asc)) {
            wrapper.orderByAsc(queryParam.getSortFields());
        } else if (StringUtils.isNotBlank(queryParam.getSortFields()) && queryParam.getSortOrder().equals(SortEnum.Desc)) {
            wrapper.orderByDesc(queryParam.getSortFields());
        } else {
            //wrapper.orderByDesc("FRecordTime");
            wrapper.orderByDesc("FOrder");
        }
        page = customerDal.selectPageList(page, wrapper);
        QueryResult<CustomerEntity> result = new QueryResult<CustomerEntity>(Math.toIntExact(page.getTotal()), page.getRecords());
        return result;
    }

    /**
     * 创建客户
     *
     * @param customerDto: 请求参数
     * @throws Exception
     */
    public void createCustomer(VerifyTokenDto tokenDto, CustomerDto customerDto) throws Exception {
        CustclassEntity classObj = customerDal.getClassById(customerDto.getFclassid());
        if (Objects.isNull(classObj)) {
            throw new BusinessException("所属分类不存在");
        }
        CustomerEntity entity = ICustomerMapper.INSTANCE.toEntity(customerDto);
        entity.setFcode(getCustomerCode(classObj.getFzjcode()));
        entity.setFcustid(Helper.GetId());
        entity.setFrecorder(tokenDto.getFuserid());
        entity.setFrecordername(tokenDto.getFfullname());
        entity.setFrecordtime(DateUtil.date());
        int count = customerDal.insertCustomer(entity);
        if (count < 1) {
            throw new BusinessException("创建客户失败");
        }
    }

    /**
     * 更新客户
     *
     * @param customerDto: 请求参数
     * @throws Exception
     */
    public void updateCustomer(VerifyTokenDto tokenDto, CustomerDto customerDto) throws Exception {

        CustomerEntity entity = ICustomerMapper.INSTANCE.toEntity(customerDto);
        entity.setFlastmodifier(tokenDto.getFuserid());
        entity.setFlastmodifiername(tokenDto.getFfullname());
        entity.setFlastmodifytime(DateUtil.date());
        int count = customerDal.updateCustomer(entity);
        if (count < 1) {
            throw new BusinessException("更新客户失败");
        }
    }

    /**
     * 删除客户
     *
     * @param customerId: 客户ID
     * @throws Exception
     */
    public void deleteCustomer(String customerId) throws Exception {
        CustomerEntity retObj = customerDal.getById(customerId);
        if (Objects.isNull(retObj)) {
            throw new BusinessException("客户不存在");
        }
        CustomerEntity tmpObj = new CustomerEntity();
        tmpObj.setFcustid(customerId);
        tmpObj.setFcode(StrUtil.format("{}_{}", retObj.getFcode(), System.currentTimeMillis()));
        tmpObj.setState(StateEnum.Delete.getValue());
        int count = customerDal.updateCustomer(tmpObj);
        if (count < 1) {
            throw new BusinessException("删除客户失败");
        }
    }

    /**
     * 改变客户状态
     *
     * @param customerId: 客户ID
     * @param stateEnum:  状态
     * @throws Exception
     */
    public void changeCustomerState(String customerId, StateEnum stateEnum) throws Exception {
        CustomerEntity tmpObj = new CustomerEntity();
        tmpObj.setFcustid(customerId);
        tmpObj.setState(stateEnum.getValue());
        int count = customerDal.updateCustomer(tmpObj);
        if (count < 1) {
            throw new BusinessException("改变客户状态失败");
        }
    }

    /**
     * 获取拼音首字母
     *
     * @param name: 名字
     * @return
     */
    private String getPinyinInitial(String name) {
        //return PinyinUtil.getFirstLetter(name, "");
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        Pinyin4jEngine engine = new Pinyin4jEngine(format);
        return engine.getFirstLetter(name, "");
    }

    /**
     * 根据客户分类助记码，生成客户编号
     *
     * @param classZJCode
     * @return
     */
    private String getCustomerCode(String classZJCode) {
        return customerDal.getCustCode(classZJCode);
    }
}
